
import { Object3D, Mesh, Material,Group } from 'three'
import {MeshStandardMaterial} from 'three'

import { OBJLoader, } from 'three/examples/jsm/loaders/OBJLoader'
import { GLTFLoader, } from 'three/examples/jsm/loaders/GLTFLoader'

import { MTLLoader, } from 'three/examples/jsm/loaders/MTLLoader'
 
import {frameColorTexture    } from './TTexture'
import {frameRoughnessTexture} from './TTexture'
import {frameMetalnessTexture} from './TTexture'
import {frameDisplaceTexture } from './TTexture'
 
const objLoader :OBJLoader = new  OBJLoader();
const mtlLoader :MTLLoader = new  MTLLoader();
 
// //考虑到带有贴图的obj需要先加载贴图 后加载模型 并把贴图放上去
// //又应为这里采用异步方式  故这里采用较为复杂的写法 
// //但是通常推荐贴图 进入threejs 然后使用threejs的材质渲染完成后  再贴上模型
// export const framePromise = new Promise<Group>((resolve, reject) => {
//     mtlLoader.loadAsync('/mix/frame.mtl').then(materialCreator =>{ 
//         objLoader
//         .setMaterials(materialCreator)
//         .loadAsync( '/mix/frame.obj')
//         .then(group => { resolve(group); })
//         .catch(err=>{reject(err);});
//     }).catch(err=>{reject(err);});
// });
 

//准备材质
const frameMaterial:MeshStandardMaterial = new  MeshStandardMaterial({ 
    map: frameColorTexture ,
    roughnessMap: frameRoughnessTexture,
    bumpMap: frameDisplaceTexture,
    metalnessMap:frameMetalnessTexture
});

//===================================================================
//载入模型 添加材质
export const framePromise = new Promise<Mesh>((resolve, reject) =>{ 
    objLoader.loadAsync( '/mix/frame.obj').then(group=>{
        if(group.children[0] instanceof Mesh){          
            const frameMesh :Mesh=group.children[0] as Mesh;
            (frameMesh.material as Material).dispose();
            frameMesh.material = frameMaterial;
            frameMesh.position.y = 10;
            frameMesh.position.z = -5;
            frameMesh.rotation.y = -0.5 * Math.PI;
            frameMesh.scale.set(0.5,0.5,0.5);
            resolve(frameMesh);
        }
    }).catch(err=>{reject(err);});
});


//另外一种加载OBJ方式  Mesh | null 保证返回类型
export const createFrame = async function():Promise<Mesh | null>{
    //首先等待模型几何载入完成
    const group = await objLoader.loadAsync( '/mix/frame.obj');
    //然后进行贴图 移动等
    if(group instanceof Group){
        const frameMesh :Mesh=group.children[0] as Mesh;
        (frameMesh.material as Material).dispose();
        frameMesh.material = frameMaterial;
        frameMesh.position.y = 5;
        frameMesh.position.z = -5;
        frameMesh.rotation.y = -0.5 * Math.PI;
        frameMesh.scale.set(0.5,0.5,0.5);
        return frameMesh;
    }
    else{
        console.error(group);
        return null; //不成功就返回空
    }
}

//单纯加载obj
// export const framePromise = objLoader.loadAsync( '/mix/frame.obj', );
 
//===================================================================

//===================================================================

//gltf
const gltfLoader:GLTFLoader = new GLTFLoader();
//单纯加载gltf
// export const gltfPromise = gltfLoader.loadAsync( '/model/LOGO2021-EVE-004--.gltf', );
//复杂加载gltf  返回gltf场景内所有物体
var gltfModelPath = '/model/LOGO2021-EVE-004--.gltf';
export const gltfPromise = new Promise<Object3D[]>((resolve, reject) =>{ 
    gltfLoader.loadAsync(gltfModelPath).then(group=>{ resolve
       const meshs: Object3D[] =[];
        group.scene.children.forEach((g)=>{ 
            g.position.y = 20;
            g.rotation.x = Math.PI * 0.5; 
            if(g instanceof Object3D)
            { meshs.push(g as Object3D); }
            resolve(meshs);
        } ) 
    }).catch(err=>{reject(err);});
})

 
//另外一种加载gltf方式 Object3D[]保证返回类型
export const createLogo = async function():Promise<Object3D[] >{
    //首先等待模型几何载入完成
    const group = await gltfLoader.loadAsync(gltfModelPath);
    //然后进行贴图 移动等
    const meshs: Object3D[] =[];
    group.scene.children.forEach((g)=>{ 
        g.position.y = 10;
        g.rotation.x = Math.PI * 0.5; 
        if(g instanceof Object3D)
        { meshs.push(g as Object3D); } 
    }) ;
    return meshs;
}
 
//===================================================================